#ifndef _DEFINITIONS_
#define _DEFINITIONS_

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h> 
#include <sys/socket.h>
#include <netinet/in.h>
#include <strings.h>
#include <signal.h>
#include <string>
#include <pthread.h>
#include <queue>
#include <list>

# define max_load_size 1450
# define max_hdr_size 4
# define max_pkt_size 1454

extern FILE *fp;
extern FILE *fp1;

extern int last_pack;

using namespace std;

class Data
{
	public: 
		 Data(string hostname, int portno, uint64_t fsize, FILE* fipo){
		   setHostname(hostname);
           setPortNum(portno);
		   setfileSize(fsize);
		   setfilePointer(fipo);
	    }

		void setHostname(string hName) {
		  	hostname = hName;
		}
		void setPortNum(int portNum) {
            portno = portNum;
		} 
        void setfileSize(uint64_t fileSize) {
            fsize = fileSize;
		}
		void setfilePointer(FILE* fipo) {
			fp = fipo;
		}
        
		string getHostname() {
		  	return hostname;
		}
		int getPortNum() {
            return portno;
		} 
        uint64_t getfileSize() {
            return fsize;
		}
		FILE* getfilePointer(){
			return fp;
		}

 
	private:
		string hostname;
	    int portno;
		uint64_t fsize;
		FILE* fp;
};


// --------------------- Function Declarations -----------------------------// Begin

void *tcp_thread_server_func(void*);

void *tcp_thread_client_func(void*);

void *udp_thread_server_func(void*);

void *udp_thread_client_func(void*);

void error(const char *);

void *udp_thread_duplicate_client_func(void*);

int sock_ready(int);

int sock_ready_client(int);

void *udp_dup_func(void* d2);

void *udp_dup_send_func(void* d2);

void *udp_nack_client(void* d2);

double mytime(void);

// --------------------- Function Declarations -----------------------------// End

//Define variables -------------------------------------------------------//Begin

extern Data* d1;
extern uint64_t fileSize;
extern bool file_complete_flag;
extern int complete_flag;
extern uint32_t num_packets;
extern unsigned char dupBuffer1[2500];
extern long fsize;
//Define variables -------------------------------------------------------//End


//Global Declarations of Locks begin ------------------------------->

extern pthread_mutex_t synch_lock;
extern pthread_mutex_t dup_lock;
extern pthread_cond_t wakeup_tcp;
extern pthread_cond_t wakeup_udp;
extern pthread_cond_t dup_cond;
extern pthread_mutex_t queue_lock;
extern pthread_cond_t queue_cond;
extern pthread_mutex_t chunk_lock;
extern pthread_cond_t chunk_cond;
extern pthread_cond_t sleep_cond;
extern pthread_mutex_t sleep_lock;
extern pthread_mutex_t queue_dup_lock;


//Global Declarations of Locks end --------------------------------->


#endif
